package com.uminho.calendar;

import java.text.SimpleDateFormat;
import java.util.Date;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.view.Window;
import android.view.animation.Animation;
import android.view.animation.Transformation;
import android.widget.AbsListView;
import android.widget.BaseExpandableListAdapter;
import android.widget.Button;
import android.widget.ExpandableListAdapter;
import android.widget.ExpandableListView;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import com.uminho.egendme.Agenda;
import com.uminho.egendme.Calendar;
import com.uminho.egendme.R;
import com.uminho.http.Webservice;
import com.uminho.objects.Appointment;
import com.uminho.tools.Disponibilidades;

/****
 * c* Calendar/AppointmentDialog DESCRIPTION Classe responsável pelo suporte à
 * vista de uma marcação
 * 
 **** 
 */

public class AppointmentDialog extends Dialog implements OnClickListener {
	ExpandableListView lista = null;
	private Context context = null;
	ExpandableListAdapter mAdapter = null;
	Appointment appointment = null;
	Button unassignAppointment = null, addFavorites = null,
			appointmentDelayed = null;
	Handler messages = null;
	ProgressDialog myProgressDialog = null;

	public AppointmentDialog(Context context, Appointment appointment) {
		super(context, R.style.WindowTitleBackground);
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		this.context = context;
		this.appointment = appointment;

		setContentView(R.layout.appointment_line);
		// dialog paramters
		LayoutParams params = getWindow().getAttributes();
		params.height = LayoutParams.FILL_PARENT;
		getWindow().setAttributes(
				(android.view.WindowManager.LayoutParams) params);
		params.width = LayoutParams.FILL_PARENT;
		getWindow().setAttributes(
				(android.view.WindowManager.LayoutParams) params);

		// icon
		ImageView appointmentIcon = (ImageView) findViewById(R.id.imgViewAppointmentIcon);
		Drawable draw = appointment.getService().getAvatar();
		if (draw != null)
			appointmentIcon.setImageDrawable(draw);

		// init and end time
		TextView textInitDate, textEndDate, serviceName, category, date, resourceName, resourceDescription, taskName, taskDescription;
		textInitDate = (TextView) findViewById(R.id.textViewDinicio);
		textEndDate = (TextView) findViewById(R.id.textViewDfim);
		serviceName = (TextView) findViewById(R.id.serviceName);
		category = (TextView) findViewById(R.id.category);
		date = (TextView) findViewById(R.id.date);
		resourceName = (TextView) findViewById(R.id.resourceName);
		resourceDescription = (TextView) findViewById(R.id.resourceDescription);
		taskName = (TextView) findViewById(R.id.taskName);
		taskDescription = (TextView) findViewById(R.id.taskDescription);

		SimpleDateFormat dateFormat = new SimpleDateFormat("d MMMM, yyyy");
		SimpleDateFormat timeFormat = new SimpleDateFormat("HH'h'mm'm'");
		textInitDate.setText(timeFormat.format(appointment.getStartDate()
				.getTime()));
		textEndDate.setText(timeFormat.format(appointment.getEndDate()
				.getTime()));
		date.setText(dateFormat.format(appointment.getStartDate().getTime()));
		resourceName.setText(appointment.getResources().get(0).getName());
		resourceDescription.setText(appointment.getResources().get(0)
				.getDescription());
		taskName.setText(appointment.getTasks().get(0).getName());
		taskDescription.setText(appointment.getTasks().get(0).getDescription());

		serviceName.setText(appointment.getService().getTitle());
		try {
			if(appointment.getService().getCategory_id()!=null){
				String[] cats = this.getContext().getResources().getStringArray(R.array.categorieslist);
				category.setText(cats[appointment.getService().getCategory_id().intValue()]);
			}
			else
				category.setVisibility(View.GONE);
		} catch (Exception e) {
			e.printStackTrace();
		};
		View resourcesHandle = findViewById(R.id.resourcesHandle);
		View resourcesPanel = findViewById(R.id.resourcesPanel);
		resourcesHandle.setTag(resourcesPanel);

		View tasksHandle = findViewById(R.id.tasksHandle);
		View tasksPanel = findViewById(R.id.tasksPanel);
		tasksHandle.setTag(tasksPanel);

		View whenHandle = findViewById(R.id.whenHandle);
		View whenPanel = findViewById(R.id.whenPanel);
		whenHandle.setTag(whenPanel);

		View whereHandle = findViewById(R.id.whereHandle);
		View wherePanel = findViewById(R.id.wherePanel);
		whereHandle.setTag(wherePanel);

		View.OnClickListener list = new View.OnClickListener() {

			public void onClick(View v) {

				View panel = (View) v.getTag();

				boolean close;
				int finalS;
				if (panel.getVisibility() == View.VISIBLE) {
					close = true;
					finalS = View.GONE;
				} else {
					close = false;
					finalS = View.VISIBLE;
				}
				// DropDownAnim anim = new DropDownAnim(resourcesPanel, 200,
				// close);
				// resourcesPanel.startAnimation(anim);
				panel.setVisibility(finalS);
			}
		};

		resourcesHandle.setOnClickListener(list);
		tasksHandle.setOnClickListener(list);
		whereHandle.setOnClickListener(list);
		whenHandle.setOnClickListener(list);

		

		messages = new Handler() {

			@Override
			public void handleMessage(Message msg) {
				Log.d("AppointmentDialog message", "" + msg.what);

				if (msg.what == 1) {
					Toast.makeText(
							AppointmentDialog.this.getContext(),
							AppointmentDialog.this.getContext().getString(
									R.string.successaddfavorites), 3000).show();

				} else if (msg.what == 2) {
					Toast.makeText(
							AppointmentDialog.this.getContext(),
							AppointmentDialog.this.getContext().getString(
									R.string.successremoveappointment), 3000)
							.show();

				} else if (msg.what == 3) {
					Toast.makeText(
							AppointmentDialog.this.getContext(),
							AppointmentDialog.this.getContext().getString(
									R.string.successremoveappointment), 3000)
							.show();

				} else if (msg.what == 4) {
					Toast.makeText(
							AppointmentDialog.this.getContext(),
							AppointmentDialog.this.getContext().getString(
									R.string.successdelayappointment), 3000)
							.show();

				} else if (msg.what == -1) {
					Toast.makeText(
							AppointmentDialog.this.getContext(),
							AppointmentDialog.this.getContext().getString(
									R.string.impossibleaddfavorite), 3000)
							.show();
				} else if (msg.what == -2) {
					Toast.makeText(
							AppointmentDialog.this.getContext(),
							AppointmentDialog.this.getContext().getString(
									R.string.impossibleremoveappointment), 3000)
							.show();
				} else if (msg.what == -5) {
					Toast.makeText(
							AppointmentDialog.this.getContext(),
							AppointmentDialog.this.getContext().getString(
									R.string.impossibledelayappointment), 3000)
							.show();
				} else if (msg.what == -11) {
					Toast.makeText(
							AppointmentDialog.this.getContext(),
							AppointmentDialog.this.getContext().getString(
									R.string.impossiblereachtheserver), 3000)
							.show();
				} else {
					Toast.makeText(
							AppointmentDialog.this.getContext(),
							AppointmentDialog.this.getContext().getString(
									R.string.impossibleaddfavorite), 3000)
							.show();
				}
				if (myProgressDialog.isShowing())
					myProgressDialog.dismiss();
			}
		};
		// button add favorite
		addFavorites = (Button) findViewById(R.id.buttonAddFavorites);
		addFavorites.setOnClickListener(this);
		// button remove appointment
		unassignAppointment = (Button) findViewById(R.id.buttonRemoveAppointment);
		unassignAppointment.setOnClickListener(this);
		// button appointment delayed
		appointmentDelayed = (Button) findViewById(R.id.buttonDelayed);
		appointmentDelayed.setOnClickListener(this);
		/**
		 * unassign button hided
		 */
		if (appointment.isCanceled())
			hideUnassignButton();
	}

	public void hideUnassignButton() {
		unassignAppointment = (Button) findViewById(R.id.buttonRemoveAppointment);
		unassignAppointment.setVisibility(Button.GONE);
	}

	@Override
	public void onCreateContextMenu(ContextMenu menu, View v,
			ContextMenuInfo menuInfo) {
		menu.setHeaderTitle("Sample menu");
		menu.add(0, 0, 0, "");
	}

	@Override
	public boolean onContextItemSelected(MenuItem item) {
		return false;
	}

	/****
	 * c* Calendar/ExpandableList DESCRIPTION Classe responsável por oferecer
	 * suporte à Marcação
	 * 
	 **** 
	 */
	public class MyExpandableListAdapter extends BaseExpandableListAdapter {
		private String[] groups = { "Resource", "Tasck", "Users" };
		Context cont = null;

		public MyExpandableListAdapter(Context context) {
			this.cont = context;
			String resourceLable = context.getString(R.string.resource_lable);
			String taskLable = context.getString(R.string.task_lable);
			String userLable = context.getString(R.string.user_lable);
			groups[0] = resourceLable;
			groups[1] = taskLable;
			groups[2] = userLable;

			// appointment.getService().setAvatar(context.getResources().getDrawable(R.drawable.agenda));

		}

		/****
		 * f* ExpandableList/getChild DESCRIPTION Método executado para devolver
		 * o objecto associado a uma posição da lista INPUTS Posição da lista
		 * RESULT Objecto associado
		 * 
		 **** 
		 */
		public Object getChild(int groupPosition, int childPosition) {
			// return children[groupPosition][childPosition];
			if (groupPosition == 0) {
				return appointment.getResources().get(childPosition);
			} else if (groupPosition == 1) {
				return appointment.getTasks().get(childPosition);
			} else if (groupPosition == 2) {
				return appointment.getUsers().get(childPosition);
			} else
				return null;
		}

		/****
		 * f* ExpandableList/getChildId DESCRIPTION Método executado para
		 * devolver o id de um objecto filho INPUTS Posições do objecto pai
		 * RESULT Objecto filho associado
		 * 
		 **** 
		 */
		public long getChildId(int groupPosition, int childPosition) {
			return childPosition;
		}

		/****
		 * f* ExpandableList/getChildrenCount DESCRIPTION Método executado para
		 * devolver o numero de objectos filhos INPUTS Posições do objecto pai
		 * RESULT Numero de objectos filhos associados
		 * 
		 **** 
		 */
		public int getChildrenCount(int groupPosition) {
			// return children[groupPosition].length;
			if (groupPosition == 0) {
				// Log.d("test", "0");
				return appointment.getResources().size();
			} else if (groupPosition == 1) {
				// Log.d("test", "1");
				return appointment.getTasks().size();
			} else if (groupPosition == 2) {
				return appointment.getUsers().size();
			} else
				return 0;

		}

		/****
		 * f* ExpandableList/getGenericView DESCRIPTION Método responsável pelo
		 * desenho das listas principais RESULT Lista principal
		 * 
		 **** 
		 */
		public TextView getGenericView() {
			// Layout parameters for the ExpandableListView
			AbsListView.LayoutParams lp = new AbsListView.LayoutParams(
					ViewGroup.LayoutParams.WRAP_CONTENT, 64);
			lp.height = LayoutParams.FILL_PARENT;
			lp.width = LayoutParams.FILL_PARENT;

			TextView textView = new TextView(context);
			textView.setLayoutParams(lp);
			// Center the text vertically
			textView.setGravity(Gravity.CENTER_VERTICAL | Gravity.LEFT);
			// Set the text starting position
			textView.setPadding(66, 10, 10, 10);
			textView.setTypeface(null, Typeface.BOLD);

			return textView;
		}

		/****
		 * f* ExpandableList/getChildView DESCRIPTION Método responsável pelo
		 * desenho das Sub Listas INPUTS Dados da lista pai RESULT Sub lista
		 * construida
		 * 
		 **** 
		 */
		public View getChildView(int groupPosition, int childPosition,
				boolean isLastChild, View convertView, ViewGroup parent) {
			View view = convertView;
			Log.d("All ", groupPosition + " " + childPosition);

			if (view == null) {

				LayoutInflater vi = AppointmentDialog.this.getLayoutInflater();
				if (groupPosition == 0) {
					view = vi.inflate(R.layout.resource_line, null);

				} else if (groupPosition == 1) {
					view = vi.inflate(R.layout.resource_line, null);

				}
				if (groupPosition == 2) {
					view = vi.inflate(R.layout.resource_line, null);

				}
				Log.d("Appointment dialog position ", groupPosition + " "
						+ childPosition);
				TextView text1, text2, text3, text4;
				text1 = (TextView) view.findViewById(R.id.textViewResource1);
				text2 = (TextView) view.findViewById(R.id.textViewResource2);
				text3 = (TextView) view.findViewById(R.id.textViewResource3);
				text4 = (TextView) view.findViewById(R.id.textViewResource4);
				if (groupPosition == 0) {
					// resources

					text1.setText(R.string.description_lable);
					text2.setText(appointment.getResources().get(childPosition)
							.getDescription());
					text3.setText(R.string.name);
					text4.setText(appointment.getResources().get(childPosition)
							.getName());

					// textView.setText(appointment.getResources().get(0).getName());
				} else if (groupPosition == 1) {
					// Tasks

					text1.setText(R.string.description_lable);
					text2.setText(appointment.getTasks().get(childPosition)
							.getDescription());
					text3.setText(R.string.name);
					text4.setText(appointment.getTasks().get(childPosition)
							.getName());

					// textView.setText(appointment.getTasks().get(0).getName());
				} else if (groupPosition == 2) {
					// appClient

					text1.setText(R.string.name);
					text2.setText(appointment.getUsers().get(childPosition)
							.getName());
					text3.setText(R.string.address);
					text4.setText(appointment.getUsers().get(childPosition)
							.getAddress());

					// textView.setText(appointment.getUsers().get(0).getName());
				}

			}
			return view;
		}

		/****
		 * f* ExpandableList/getGroup DESCRIPTION Método executado para devolver
		 * o objecto pai dada uma posição INPUTS Posição do objecto RESULT
		 * Objecto associado
		 * 
		 **** 
		 */
		public Object getGroup(int groupPosition) {
			return groups[groupPosition];
		}

		/****
		 * f* ExpandableList/getGroup DESCRIPTION Método executado para devolver
		 * o número de objectos pai RESULT Numero de objectos pai
		 * 
		 **** 
		 */
		public int getGroupCount() {
			return groups.length;
		}

		/****
		 * f* ExpandableList/getGroup DESCRIPTION Método executado para devolver
		 * o id do objecto pai dada uma posição INPUTS Posição do objecto RESULT
		 * ID do obejcto associado
		 * 
		 **** 
		 */
		public long getGroupId(int groupPosition) {
			return groupPosition;
		}

		/****
		 * f* ExpandableList/getGroup DESCRIPTION Método executado para devolver
		 * a vista do objecto pai dada uma posição INPUTS Posição do objecto
		 * RESULT Vista do objecto associado
		 * 
		 **** 
		 */
		public View getGroupView(int groupPosition, boolean isExpanded,
				View convertView, ViewGroup parent) {
			TextView textView = getGenericView();
			textView.setText(getGroup(groupPosition).toString());
			return textView;
		}

		public boolean isChildSelectable(int groupPosition, int childPosition) {
			return true;
		}

		public boolean hasStableIds() {
			return true;
		}

	}

	public void onClick(View v) {
		// Log.d("click", "click "+v.getId()+" ");
		/**
		 * button add favorites
		 */
		if (v.getId() == R.id.buttonAddFavorites) {
			Log.d("AppointmentDialog", "Add bookmark n:");
			myProgressDialog = ProgressDialog.show(context,
					context.getString(R.string.loading),
					context.getString(R.string.addfavorites), true);

			new Thread() {
				@Override
				public void run() {
					Boolean result = false;
					try {
						Webservice w = Webservice.getInstance();
						result = w.addBookmark(appointment.getService()
								.getServiceId());
					} catch (Exception e) {
						e.printStackTrace();
						messages.sendEmptyMessage(-1);
						return;
					}
					if (result) {
						messages.sendEmptyMessage(1);
					} else {
						messages.sendEmptyMessage(-1);
					}

				}
			}.start();

		}
		/**
		 * button delete appointment
		 */
		else if (v.getId() == R.id.buttonRemoveAppointment) {
			Log.d("AppointmentDialog", "Remove app n:" + appointment.getId());
			AlertDialog.Builder builder = new AlertDialog.Builder(context);
			builder.setMessage(context.getString(R.string.realy_want_delete))
					.setCancelable(false)
					.setPositiveButton(context.getString(R.string.yes),
							new DialogInterface.OnClickListener() {
								public void onClick(DialogInterface dialog,
										int id) {
									/**
									 * aqui terá o webservice remove appointment
									 * 
									 */
									myProgressDialog = ProgressDialog.show(
											context,
											context.getString(R.string.loading),
											context.getString(R.string.removingappointment),
											true);

									new Thread() {
										@Override
										public void run() {
											Webservice w = Webservice
													.getInstance();

											Log.d("Cancel Appointment", ""
													+ appointment.getId());
											try {
												w.delAppointment(appointment
														.getId());
											} catch (Exception e) {
												// TODO Auto-generated catch
												// block;
												e.printStackTrace();
												messages.sendEmptyMessage(-2);
												return;
											}
											Date date = appointment
													.getStartDate().getTime();
											Date newDate = new Date(date
													.getYear(),
													date.getMonth(), date
															.getDate());
											Disponibilidades
													.derementBusyDays(newDate);
											Disponibilidades.saveBusyDays();
											if (context.getClass().equals(
													Calendar.class)) {

												Log.d("Favorites", "refresh");
												Intent refresh = new Intent(
														context, Calendar.class);
												context.startActivity(refresh);
												AppointmentDialog.this
												.dismiss();
												((Activity) context).finish();
												
												
												messages.sendEmptyMessage(2);
											} else if (context.getClass()
													.equals(Agenda.class)) {
												Log.d("Favorites", "refresh");
												Intent refresh = new Intent(
														context, Agenda.class);
												context.startActivity(refresh);
												((Activity) context).finish();
												AppointmentDialog.this
														.dismiss();
												messages.sendEmptyMessage(3);
											}

										}
									}.start();

								}
							})
					.setNegativeButton(context.getString(R.string.no),
							new DialogInterface.OnClickListener() {
								public void onClick(DialogInterface dialog,
										int id) {
									dialog.cancel();
								}
							});
			AlertDialog alert = builder.create();
			alert.show();

		}
		/**
		 * button appointment delayed
		 */
		else if (v.getId() == R.id.buttonDelayed) {
			myProgressDialog = ProgressDialog.show(context,
					context.getString(R.string.loading),
					context.getString(R.string.delayingappointment), true);

			new Thread() {
				@Override
				public void run() {
					Webservice w = Webservice.getInstance();
					try {
						w.delayWarning(new Integer(15), appointment.getId());

					} catch (Exception e) {
						Log.d("Delay exception", e.toString());
						e.printStackTrace();
						messages.sendEmptyMessage(-5);
						return;
					}
					Log.d("Delay sucess", appointment.getId() + "delayed");
					messages.sendEmptyMessage(4);
					return;

				}

			}.start();
		}

	}

	public class DropDownAnim extends Animation {
		int targetHeight;
		View view;
		boolean down;

		public DropDownAnim(View view, int targetHeight, boolean down) {
			this.view = view;
			this.targetHeight = targetHeight;
			this.down = down;
		}

		@Override
		protected void applyTransformation(float interpolatedTime,
				Transformation t) {
			int newHeight;
			if (down) {
				newHeight = (int) (targetHeight * interpolatedTime);
			} else {
				newHeight = (int) (targetHeight * (1 - interpolatedTime));
			}
			view.getLayoutParams().height = newHeight;
			view.requestLayout();
		}

		@Override
		public void initialize(int width, int height, int parentWidth,
				int parentHeight) {
			super.initialize(width, height, parentWidth, parentHeight);
		}

		@Override
		public boolean willChangeBounds() {
			return true;
		}
	}
	private void addField(ViewGroup parent, String label, String value, Integer link){
		if(value == null || value.length()==0)
			return;

		View v = LayoutInflater.from(getContext()).inflate(R.layout.dialogfield, parent, false);

		TextView textView = (TextView) v.findViewById(R.id.label);
		textView.setText(label+" ");
		textView = (TextView) v.findViewById(R.id.value);
		textView.setText(value);
		if(link!=null)
			textView.setAutoLinkMask(link);

		parent.addView(v);
	}

	private void addField(ViewGroup parent, String label, String value){
		addField(parent,label,value, null);
	}

	private void addDescriptiveField(ViewGroup parent, String label, String value){
		if(value == null || value.length()==0)
			return;

		View v = LayoutInflater.from(getContext()).inflate(R.layout.dialogdfield, parent, false);

		TextView textView = (TextView) v.findViewById(R.id.label);
		textView.setText(label+" ");
		textView = (TextView) v.findViewById(R.id.value);
		textView.setText(value);

		parent.addView(v);
	}

	private ViewGroup addTab(ViewGroup parent, String handleText){
		if(handleText == null || handleText.length()==0)
			return null;

		View v = LayoutInflater.from(getContext()).inflate(R.layout.dialogtab, parent, false);
		TextView textView = (TextView) v.findViewById(R.id.textHandle);
		textView.setText(handleText);

		ViewGroup panel = (ViewGroup) v.findViewById(R.id.panel);

		parent.addView(v);
		return panel;
	}

	private void addSeparator(ViewGroup parent){
		View v = LayoutInflater.from(getContext()).inflate(R.layout.dialogseparator, parent, false);
		parent.addView(v);
	}
}
